package importer;

import persistance.*;

import org.jdom.*;
import org.jdom.input.SAXBuilder;
import java.io.IOException;
import java.util.*;


public class UMLSequenceImportManager 
{

	//no need for constructor...
	
	//builds the memory node based on JDOM
	private SAXBuilder _mySAXbuilder = new SAXBuilder();

	
	//An an array list of agents, with every role that each agent plays
	private ArrayList<Agent> _theAgentList = new ArrayList<Agent>();
	
	//An array list of messages associated with each protocol file
	private ArrayList<Protocols> _theProtocolMessageList = new ArrayList<Protocols>();
	
	
	//start the module
	public void import_protocol_file(String filepath) throws IOException, JDOMException
	{			

		//An array list of messages that holds all the messages
		ArrayList<Message> _theMessageList = new ArrayList<Message>();		
		
		try
		{
			System.out.println("Parsing: " + filepath + " ...\n");
			Document myDocument = _mySAXbuilder.build("file://////" + filepath);
			//TODO: Figure out why Brooks needed to add this
			_theMessageList = buildMessageStructure(myDocument);
		}
		catch(JDOMException e)
		{
			//to be documented
			System.out.println(filepath + " is not well-formed.");
		    System.out.println(e.getMessage());
		    throw e;
			//e.printStackTrace();
			//System.exit(0);
		}
		catch(IOException e)
		{
			//to be documented
			System.out.println("Could not check " + filepath);
		    System.out.println(" because " + e.getMessage());
		    throw e;
			//e.printStackTrace();
			//System.exit(0);
		}		
		
		//create a new "protocols" object to hold all the messages associated with a protocol file
		Protocols protocol = new Protocols(filepath, _theMessageList);		
		
		_theProtocolMessageList.add(protocol);			
	}
	

	public void import_agent_file(String filepath) throws JDOMException, IOException
	{
		try
		{
			System.out.println("Parsing: " + filepath + " ...\n");
			Document myDocument = _mySAXbuilder.build("file://////" + filepath);			

			buildAgentStructure(myDocument);
		}
		catch(JDOMException e)
		{
			//to be documented
			System.out.println(filepath + " is not well-formed.");
		    System.out.println(e.getMessage());
			throw e;
		    //e.printStackTrace();
			//System.exit(0);
		}
		catch(IOException e)
		{
			//to be documented
			System.out.println("Could not check " + filepath);
		    System.out.println(" because " + e.getMessage());
			throw e;
		    //e.printStackTrace();
			//System.exit(0);
		}		
	}
	
	//builds the message structure
	public ArrayList<Message> buildMessageStructure(Document doc)
	{
		
		ArrayList<Message> _theMessageList = new ArrayList<Message>();
		
		//the top element - usually the name of the diagram
		Element top_element = doc.getRootElement();
		
		//all the children of the the top element - in this case Agents or Roles
		List elementlist = top_element.getChildren();
		
		//iterate through the Agent/Roles list
		Iterator iterator = elementlist.iterator();
		
		while(iterator.hasNext())
		{
			Object o = iterator.next();
			if(o instanceof Element)
			{
				Element current = (Element)o;

				//make sure we only get "Agent" or "Role" tags
				if(current.getName() == "Agent" || current.getName() == "Role")
				{
					buildMessages(current.getAttributeValue("name"), current.getChildren(), _theMessageList);
				}			
			}
		}
		
		//the message list has been built now but it is not sorted
		//making a comparer class based on y comparison
		yCompare compareByY = new yCompare();
		
		//sort the message list by Y coordinate
		Collections.sort(_theMessageList, compareByY);
		
		return _theMessageList;
	}
	
	//builds the messages
	public void buildMessages(String parent, List messages, List themessagelist)
	{
		
		//a list, of type "Element" to hold the children of each message
		List <Element>children = null;
		
		Iterator iterator = messages.iterator();
		
		while(iterator.hasNext())
		{
			Object o = iterator.next();
			
			if(o instanceof Element)
			{
				Element current = (Element)o;
				
				if(current.getName() == "synchronous" || current.getName() == "asynchronous")
				{					
					children = current.getChildren();
					
					//create a new message
					Message myMessage = new Message(current.getName(), current.getAttributeValue("name"), parent, children.get(0).getText(), Integer.parseInt(current.getAttributeValue("y")));
					
					//add the message to the list
					themessagelist.add(myMessage);
				}				
			}
		}			
	}
	
	//builds the agent structure
	public void buildAgentStructure(Document doc)
	{
		//the top element - usually the name of the diagram
		Element top_element = doc.getRootElement();
		
		//all the children of the the top element - in this case 
		List agentlist = top_element.getChildren();
		
		//iterate through the list of agents
		Iterator iterator = agentlist.iterator();
		
		while(iterator.hasNext())
		{
			Object o = iterator.next();
			if(o instanceof Element)
			{
				Element current = (Element)o;

				//make sure we only get "Agent"
				if(current.getName() == "Agent")
				{
					buildRoles(current.getAttributeValue("name"), current.getChildren());
				}			
			}
		}			
	}

	//builds the roles
	public void buildRoles(String parent, List roles)
	{	
		ArrayList<String> rolelist = new ArrayList<String>();
		
		Iterator iterator = roles.iterator();
				
		while(iterator.hasNext())
		{
			Object o = iterator.next();
			
			if(o instanceof Element)
			{
				Element current = (Element)o;
				
				if(current.getName() == "plays")
				{					
					rolelist.add(current.getChildText("child"));					
				}	
			}
		}	
		//create a new agent
		Agent myAgent = new Agent(parent, rolelist);
		
		//add the agent to the list
		_theAgentList.add(myAgent);
		
	}
	
	//comparator inner class to order the list of messages based on Y value
	class yCompare implements Comparator<Message>
	{
		public int compare(Message one, Message two)
		{
			return one.get_y().compareTo(two.get_y());
		}
	}

	public ArrayList<Agent> get_theAgentList() {
		return _theAgentList;
	}


	public void set_theAgentList(ArrayList<Agent> agentList) {
		_theAgentList = agentList;
	}


	public ArrayList<Protocols> get_theProtocolMessageList() {
		return _theProtocolMessageList;
	}


	public void set_theProtocolMessageList(ArrayList<Protocols> protocolMessageList) {
		_theProtocolMessageList = protocolMessageList;
	}		
}
